package co.yixiang.security.buyer;

import co.yixiang.cache.Cache;
import co.yixiang.common.properties.IgnoredUrlsProperties;
import co.yixiang.modules.security.security.JwtAccessDeniedHandler;
import co.yixiang.modules.security.security.JwtAuthenticationEntryPoint;
import co.yixiang.modules.security.security.TokenConfigurer;
import co.yixiang.modules.security.security.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.CorsFilter;

/**
 * spring Security 核心配置类 Buyer安全配置中心
 *
 * @author Chopper
 * @version v4.0
 * @since 2020/11/14 16:20
 */

@Slf4j
@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
public class BuyerSecurityConfig{

    /**
     * 忽略验权配置
     */
    @Autowired
    private IgnoredUrlsProperties ignoredUrlsProperties;

    /**
     * spring security -》 权限不足处理
     */
    // @Autowired
    // private CustomAccessDeniedHandler accessDeniedHandler;

    @Autowired
    private Cache cache;
    @Autowired
    private CorsFilter corsFilter;
    @Autowired
    private TokenUtil tokenUtil;
    @Autowired
    private JwtAuthenticationEntryPoint authenticationErrorHandler;
    @Autowired
    private JwtAccessDeniedHandler jwtAccessDeniedHandler;
    @Autowired
    private ApplicationContext applicationContext;

//    @Bean
//    public WebSecurityCustomizer webSecurityCustomizer() {
//        // 仅仅作为演示
//        return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
//    }

    /**
     * 处理 给 app(前后端分离) 端使用的过滤链
     * 以 json 的数据格式返回给前端
     */
    @Bean
    @Order(1)
    public SecurityFilterChain appSecurityFilterChain(HttpSecurity http) throws Exception {
        // 只处理 /api 开头的请求
        return http
                // 禁用 CSRF
                .csrf().disable()
                .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
                // 授权异常
                .exceptionHandling()
                .authenticationEntryPoint(authenticationErrorHandler)
                .accessDeniedHandler(jwtAccessDeniedHandler)

                // 防止iframe 造成跨域
                .and()
                .headers()
                .frameOptions()
                .disable()

                // 不创建会话
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

                .and()
                .authorizeRequests()
                // 静态资源等等
                .antMatchers(
                        HttpMethod.GET,
                        "/*.html",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js",
                        "/webSocket/**"
                ).permitAll()
                // swagger 文档
                .antMatchers("/swagger-ui.html").permitAll()
                .antMatchers("/swagger-resources/**").permitAll()
                .antMatchers("/webjars/**").permitAll()
                .antMatchers("/*/api-docs").permitAll()
                .antMatchers("/v2/api-docs-ext").permitAll()
                //.antMatchers("/api/wxmp/**").permitAll()
                // 文件
                .antMatchers("/avatar/**").permitAll()
                .antMatchers("/file/**").permitAll()
                // 阿里巴巴 druid
                .antMatchers("/druid/**").permitAll()
                .antMatchers("/api/canvas/**").permitAll()
                .antMatchers("/api/canvas/**").permitAll()
                // 放行OPTIONS请求
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                // 静态资源等等
                .antMatchers("/buyer/auth/**").permitAll()
                // 放行OPTIONS请求
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                // 拦截 /buyer下的所有请求 // 用户认证
                //.antMatchers("/buyer/user/**").authenticated()
                .antMatchers("/buyer/payment/cashier/notify/WECHAT").permitAll()
                .antMatchers("/buyer/user/**","/buyer/order/**","/buyer/payment/cashier/pay","/buyer/trade/**").authenticated()
                //添加JWT认证过滤器
                .and().apply(securityConfigurerAdapter()).and().build();
    }
    private TokenConfigurer securityConfigurerAdapter() {

        return new TokenConfigurer(tokenUtil,cache);
    }

}
